/*
 * Copyright (C) 2023, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

import QtQuick 2.12
import org.ukui.notification.ui 1.0

import org.ukui.quick.items 1.0 as UkuiItems
import org.ukui.quick.platform 1.0 as Platform

import QtQuick.Layouts 1.12
import QtQml.Models 2.12

Flickable {
    property int itemWidth: 374
    property int itemRadius: 12
    property int maxHeight: popupNotificationWindow.maximumHeight
    property int duration: 300
    property real preContentY: 0
    boundsBehavior: isLiteMode ? Flickable.StopAtBounds : Flickable.DragAndOvershootBounds

    onMovingChanged: {
        if (moving) {
            preContentY = contentY;
            popupNotificationWindow.enableWindowBlur(false);
        } else {
            popupNotificationWindow.updataGroupsPosition(contentY - preContentY);
            popupNotificationWindow.enableWindowBlur(true);
        }
    }

    width: itemWidth
    height: childrenRect.height > maxHeight ? maxHeight : childrenRect.height
    interactive: childrenRect.height > maxHeight

    contentHeight: baseLayout.height
    contentWidth: baseLayout.width

    Column {
        id: baseLayout
        width: itemWidth
        height: childrenRect.height
        spacing: 8

        onHeightChanged: {
            baseRepeater.updateGroupsRegion();
        }

        move: Transition {
            enabled: !isLiteMode
            SequentialAnimation {
                NumberAnimation { properties: "y"; easing.type: Easing.InOutQuad; duration: duration }
                ScriptAction { script: popupNotificationWindow.enableWindowBlur(true) }
            }
        }

        Repeater {
            id: baseRepeater
            property var perAppItemsList: []

            function updateGroupsRegion() {
                var windowRegion = {"regions": []};

                for (var i = 0; i < baseRepeater.count; i++) {
                    var groupRegion = {};
                    groupRegion["count"] = baseRepeater.itemAt(i).itemCount;
                    groupRegion["height"] = baseRepeater.itemAt(i).itemHeight;
                    groupRegion["width"] = itemWidth;
                    groupRegion["radius"] = itemRadius;

                    windowRegion["regions"].push(groupRegion);
                }
                popupNotificationWindow.updataWindowRegion(windowRegion, contentY);
            }
            onCountChanged: {
                updateGroupsRegion();
            }
        }
        Component.onCompleted: {
            baseRepeater.model = baseModel;
        }

        DelegateModel {
            id: baseModel
            model: groupModel
            rootIndex: modelIndex(-1)

            delegate: Item {
                id: componentPerApp
                property int groupIndex: model.groupIndex
                property int itemHeight: collapsedLayout.height
                property int itemCount

                width: childrenRect.width
                height: childrenRect.height

                // ******************[perApp]****************

                Component.onCompleted: {
                    modelPreApp.model =  groupModel;
                    modelPreApp.rootIndex = modelPreApp.modelIndex(groupIndex);
                    repeaterPerApp.model = modelPreApp;
                }

                DelegateModel {
                    id: modelPreApp
                    delegate: Item {
                        id: delegateItem
                        height: childrenRect.height
                        width: itemWidth
                        property bool removeToClose: false
                        state: "add"

                        Component.onCompleted: {
                            z = repeaterPerApp.count - index;
                            delegateContent.background.alpha = ((index === 0 && (repeaterPerApp.count > 1)) ? 1 : 0.85);
                        }

                        transform: Scale { yScale: collapsedLayout.height / height }

                        states: [
                            State {
                                name: "normal"
                                PropertyChanges {
                                    target: delegateContent
                                    x: 0; opacity: 1
                                }
                            },
                            State {
                                name: "add"
                                PropertyChanges {
                                    target: delegateContent
                                    x: itemWidth; opacity: 0
                                }
                            },
                            State {
                                name: "remove"
                                PropertyChanges {
                                    target: delegateContent
                                    x: itemWidth; opacity: 0
                                }
                            }
                        ]
                        transitions: [
                            Transition {
                                to: "normal"
                                enabled: !isLiteMode
                                SequentialAnimation {
                                    ScriptAction { script: popupNotificationWindow.enableWindowBlur(false) }
                                    NumberAnimation { properties: "x, opacity"; easing.type: Easing.Bezier; easing.bezierCurve: [0.12,0,0.18,1,1,1]; duration: 300 }
                                    ScriptAction { script: popupNotificationWindow.enableWindowBlur(true) }
                                }
                            },
                            Transition {
                                to: "remove"
                                enabled: !isLiteMode
                                SequentialAnimation {
                                    ScriptAction {
                                        script: {
                                            if (repeaterPerApp.count === 1) {
                                                popupNotificationWindow.enableWindowBlur(false)
                                            }
                                        }
                                    }
                                    NumberAnimation { properties: "x, opacity"; easing.type: Easing.Bezier; easing.bezierCurve: [0.42,0,1,1,1,1]; duration: 200}
                                    ScriptAction {
                                        script: {
                                            delegateItem.toRemoveScript();
                                        }
                                    }
                                }
                            }
                        ]

                        onStateChanged: {
                            if (isLiteMode) {
                                if (state === "remove") {
                                    delegateItem.toRemoveScript();
                                }
                            }
                        }

                        function toRemoveScript() {
                            if (delegateItem.removeToClose) {
                                sourceModel.closeNotification(model.id);
                            } else {
                                sourceModel.execAction(model.id, delegateContent.action);
                            }
                        }
                        PopupNotificationItem {
                            id: delegateContent
                            property string action: ""
                            height: childrenRect.height
                            width: itemWidth
                            background.radius: itemRadius
                            pcTips.text: qsTr("%1 more notifications").arg(repeaterPerApp.count - 1)
                            pcTips.visible: repeaterPerApp.count > 1

                            onActionExecuted: function (action) {
                                delegateContent.action = action;
                                if (model.resident) {
                                    sourceModel.execAction(model.id, action);
                                } else {
                                    delegateItem.removeToClose = false;
                                    delegateItem.state = "remove";
                                }
                            }

                            onNotificationClosed: {
                                delegateItem.removeToClose = true;
                                delegateItem.state = "remove";
                            }

                            onClicked: {
                                if (model.hasDefaultAction) {
                                    if (model.resident) {
                                        sourceModel.execAction(model.id, "");

                                    } else {
                                        delegateContent.action = "";
                                        delegateItem.removeToClose = false;
                                        delegateItem.state = "remove";
                                    }
                                }
                            }

                            Component.onCompleted: {
                                delegateItem.state = "normal";
                                if (isLiteMode) {
                                    popupNotificationWindow.enableWindowBlur(true);
                                }
                            }
                        }
                    }
                }

                Column {
                    width: itemWidth
                    height: childrenRect.height

                    Item {
                        id: collapsedLayout
                        width: itemWidth
                        height: firstItemHeight
                        property int firstItemHeight

                        Repeater {
                            id: repeaterPerApp
                            onCountChanged: {
                                componentPerApp.itemCount = repeaterPerApp.count;
                                if (count > 0) {
                                    collapsedLayout.firstItemHeight = itemAt(0).height;
                                }
                                baseRepeater.updateGroupsRegion();
                            }
                        }
                    }

                    Column {
                        id: foldingBar
                        height: (repeaterPerApp.count > 1) ? childrenRect.height : 0
                        width: itemWidth
                        property int barHeight: 8

                        Item {
                            height: repeaterPerApp.count > 1 ? foldingBar.barHeight : 0
                            width: itemWidth
                            clip: true

                            UkuiItems.StyleBackground {
                                useStyleTransparency: false
                                paletteRole: Platform.Theme.Base
                                alpha: 0.5
                                radius: itemRadius
                                anchors.horizontalCenter: parent.horizontalCenter
                                anchors.bottom: parent.bottom

                                width: parent.width * 0.95
                                height: radius * 2
                            }
                        }
                        Item {
                            height: repeaterPerApp.count > 2 ? foldingBar.barHeight : 0
                            width: itemWidth
                            clip: true

                            UkuiItems.StyleBackground {
                                useStyleTransparency: false
                                paletteRole: Platform.Theme.Base
                                alpha: 0.2
                                radius: itemRadius
                                anchors.horizontalCenter: parent.horizontalCenter
                                anchors.bottom: parent.bottom

                                width: parent.width * 0.95 * 0.95
                                height: radius * 2
                            }
                        }
                    }
                }
            }
        }
    }
}
